package com.example.graduationdesign.filter;

import cn.hutool.json.JSONUtil;
import com.example.graduationdesign.constant.Constant;
import com.example.graduationdesign.pojo.vo.Result;
import com.example.graduationdesign.pojo.vo.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 请求拦截器
 */
@Slf4j
@javax.servlet.annotation.WebFilter
@Component
public class WebFilter implements Filter {
    // 路径匹配器，支持通配符
    private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 1. 获取本次请求
        String requestURI = request.getRequestURI();

        System.out.println(requestURI);
        // 不需要处理的请求
        if (requestURI.startsWith("/chat")) {
            // 不需要处理
            filterChain.doFilter(request, response);
            return;
        }

        String[] urls = new String[]{"/user/logout","/user/email/register",
                "/user/update_city","/user/upload/avatar","/user/login",
                "/user/email","/user/forget","/user/register",
                "/user/upload/audio","/user/yuding","/user/jingdian"};

        // 2. 判断本次请求是否需要处理
        if (check(urls, requestURI)) {
            // 不需要处理
            filterChain.doFilter(request, response);
            System.out.println(11111111);
            return;
        }
        System.out.println("11111111111");

        // 3. 检查 token 是否有效
        String token = request.getHeader("token");

        if (checkToken(token)) {
            // 有效
            filterChain.doFilter(request, response);
            return;
        }

        // 4. 未登录或者登录token失效，通过输出流向客户端页面相应数据
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(JSONUtil.toJsonStr(Result.failure(ResultCode.USER_NOT_LOGIN)));
    }

    /**
     * 检查请求路径是否需要放行
     *
     * @param urls
     * @param requestURI
     * @return
     */
    private boolean check(String[] urls, String requestURI) {
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查用户token
     *
     * @param token
     * @return
     */
    public boolean checkToken(String token) {
        // 用户
        String userKey = Constant.CLIENT_TOKEN + token;
        System.out.println(userKey);
        Boolean hasStaffKey = redisTemplate.hasKey(userKey);
        if (Boolean.TRUE.equals(hasStaffKey)) {
            // 存在，刷新 token 时间
            // 1. 获取当前数据剩余时间
            Long expire = redisTemplate.getExpire(userKey, TimeUnit.MINUTES);
            // 2. 判断是否需要刷新
            if (expire != null && expire <= Constant.TOKEN_EXIST_TIME * 0.7) {
                // 刷新时间
                redisTemplate.expire(userKey, Constant.TOKEN_EXIST_TIME, TimeUnit.MINUTES);
            }
            return true;
        }

        return false;
    }
}
